#include "stdafx.h"
#include <time.h>
#include <sys/utime.h>
#include <iostream>
#include <atlcomcli.h>
#include <CommCtrl.h>
#include <shellapi.h>
#include <Windows.h>
#include <string.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#include <io.h>
#include <map>
#include <set>
#include <VersionHelpers.h>
#include "Logging.h"
#include "Hooks.h"
#include "StartMenuDll.h"
#include <XmlDomDid.h>
#include <WtsApi32.h>
#include <PowrProf.h>

#pragma data_seg("Shared")		//these variables will be shared among all processes to which this dll is linked

const int MAIN_TASK_BAR = 0;
const int FIRST_BUTTON_BITMAP = 6801;

HHOOK hkKey = NULL;			
HHOOK hProgmanHook = NULL;
HHOOK hTaskBarHook = NULL;
HHOOK hSMTaskBarHook = NULL;
HHOOK hAppManager = NULL;
HHOOK hMouse = NULL;
HHOOK hKeyboard = NULL;
HHOOK hStartButton = NULL;
HHOOK hNewTaskbar = NULL;
//HINSTANCE hInstHookDll=NULL;
//HWND g_TaskBar;
HWND g_Rebar;
HWND g_SwitchList;
HWND g_ProgWin;
HWND g_WinKStartManagement;
HWND g_WinKStartManagementKey;
HWND g_MainTaskBar = NULL;
//HWND g_WinStartButton, g_StartButtonOld;
DWORD dwRefData;
UINT uIdSubclass;

static int g_LastTaskbar = MAIN_TASK_BAR;
static int g_NextTaskbar = 0;

bool s_bShiftPressed = false;
static bool g_bNotReplacedSecondStartButtonPressed = false;
int g_bLastStateMouse = -1;
int g_Option_DMS = 0;
int g_Option_DHE = 0;
int g_Option_BKO = 0;
int g_Option_SBKO = 0; 
LPWSTR *g_OptionTranslationsPath, *g_OptionLoggingPath;

int g_TestValue = 0;

std::map<UINT, char *> g_MsgCodeNames;
static std::set<HWND> g_EdgeWindows;
static DWORD g_StartButtonOldSizes[12];

#define ABE_LEFT        0
#define ABE_TOP         1
#define ABE_RIGHT       2
#define ABE_BOTTOM      3

#define IDD_LOGOFF                      104
#define IDD_LOGOFFR                     105

#define IDC_PROMPT                      1015
#define IDC_STATICICON1                 1053

enum {
	CMD_EXPLORER = 1,
	CMD_RUN,
	CMD_SEARRCH,
	CMD_TASKMANAGER,
	CMD_SYSTEMCONTROL,
	CMD_SYSTEMPROPERTIES,
	CMD_PROGRAMS,
	CMD_COMMANDSHELL,
	CMD_COMMANDSHELLELEVATED,
	CMD_POWERSHELL,
	CMD_POWERSHELLELEVATED,
	CMD_MOBILITYCENTER,
	CMD_ENERGYOPTIONS,
	CMD_EVENTVIEWER,
	CMD_DEVICEMANAGER,
	CMD_NETWORKCONNECTIONS,
	CMD_DISKMANAGEMENT,
	CMD_COMPUTERMANAGEMENT,
	CMD_SETTINGS,
	CMD_EXIT,
	CMD_WINDOWS_SESSIONCONTROL,
	CMD_SHUTDOWN,
	CMD_RESTART,
	CMD_SLEEP,
	CMD_HIBERNATE,
	CMD_LOCK,
	CMD_LOGOFF,
	CMD_SWITCH_USER,
	CMD_WINDOWS_HELP,
	CMD_UNDOCK,
	CMD_DISCONNECT
};

#pragma data_seg()

#pragma comment(linker,"/section:Shared,rws")


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch(ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		g_Instance = (HINSTANCE)hModule;		//we initialize our variable with the value that is passed to us
		break;
	}
    return TRUE;
}

LRESULT CALLBACK HookNewTaskbar(int nCode, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;																//a pointer to hold the MSG structure that is passed as lParam
	msg = (MSG *)lParam;

	LogMessage(*msg, "HookNewTaskbar", LOG_ACTIONS);

	return CallNextHookEx(hNewTaskbar, nCode, wParam, lParam);
}

LRESULT CALLBACK procCharMsg(int nCode,WPARAM wParam, LPARAM lParam)		//this is the hook procedure
{
	MSG *msg;																//a pointer to hold the MSG structure that is passed as lParam
	msg = (MSG *)lParam;

	//LogMessage(*msg, "procCharMsg", LOG_MESSAGES);

	return CallNextHookEx(hkKey,nCode,wParam,lParam);						//passing this message to target application
}

LRESULT CALLBACK HookProgMan(int code, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	msg = (MSG *)lParam;

	if (msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST) {

		if (!g_bNotReplacedSecondStartButtonPressed) {
			bool bShiftPressed = (GetAsyncKeyState(VK_SHIFT) < 0);


			RECT rcTaskbar;

			GetWindowRect(g_MainTaskBar, &rcTaskbar);

			POINT pStartPos;
			UINT uiPosition = GetStartButtonTPosition(g_MainTaskBar);

			if (uiPosition == ABE_LEFT) {
				pStartPos.x = rcTaskbar.right;
				pStartPos.y = rcTaskbar.top;
			}
			else if (uiPosition == ABE_TOP) {
				pStartPos.x = rcTaskbar.left;
				pStartPos.y = rcTaskbar.bottom;
			}
			else {
				pStartPos.x = rcTaskbar.left;
				pStartPos.y = rcTaskbar.top;
			}

			if (bShiftPressed) {
				//Shift - Key is Pressed on keyboard by the user
				if (g_Option_SBKO == 1){
					msg->message = WM_NULL;
					//Opens WinKStart - Startmenu
					if (!g_WinKStartManagementKey) g_WinKStartManagementKey = FindWindowExW(NULL, NULL, L"WinKStart.CWinKStartManagement", NULL);
					PostMessage(g_WinKStartManagementKey, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));


				}
				else if (g_Option_SBKO == 2){
					//Opens Metro StartScreen
					//Message run the normal way
				}
				else {
					//other value in g_SBKO example 0 -> nothing happens
					msg->message = WM_NULL;
				}

			}
			else {
				//Shift - Key is not pressed on keyboard
				if (g_Option_BKO == 1) {
					//Opens WinKStart - Startmenu					
					if (!g_WinKStartManagementKey) g_WinKStartManagementKey = FindWindowExW(NULL, NULL, L"WinKStart.CWinKStartManagement", NULL);
					PostMessage(g_WinKStartManagementKey, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));

					PostMessage(g_WinKStartManagementKey, WM_ACTION_TEST_VALUE, 0, GetTaskbars());

					msg->message = WM_NULL;
				}
				else if (g_Option_BKO == 2){
					//Opens Metro StartScreen
					//Message run the normal way
				}
				else {
					//other value in g_BKO example 0 -> nothing happens
					msg->message = WM_NULL;
				}
			}
		}
		else {
			//User has pressed a not replaced second StartButton
			//Use Default Windows function
			g_bNotReplacedSecondStartButtonPressed = false;
		}
	}

	return CallNextHookEx(hProgmanHook, code, wParam, lParam);
}

LRESULT CALLBACK HookTaskBar(int code, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	msg = (MSG *)lParam;
	
	//LogMessage(*msg, "HookTaskBar", LOG_MESSAGES);
	
	return CallNextHookEx(hTaskBarHook, code, wParam, lParam);
}

LRESULT CALLBACK SMHookTaskBar(int code, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	msg = (MSG *)lParam;

	//LogMessage(*msg, "SMHookTaskBar", LOG_MESSAGES);

	return CallNextHookEx(hSMTaskBarHook, code, wParam, lParam);
}

static LRESULT CALLBACK HookAppManager(int code, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	msg = (MSG *)lParam;

	if (msg->message == WM_MOUSEFIRST || msg->message == WM_MOUSEMOVE || msg->message == WM_LBUTTONDOWN){
		wchar_t className[256] = { 0 };

		GetClassNameW(msg->hwnd, className, _countof(className));
		//Option to enable/disable hot edges
		//notice: if hot edges are disabled, ImmersiveSwitchlist is already disabled!!!!!!
		if (g_Option_DHE == 0) {
			if (wcscmp(className, L"EdgeUiInputWndClass") == 0) {
				msg->message = WM_NULL;
				g_EdgeWindows.insert(msg->hwnd);
				ShowWindow(msg->hwnd, SW_HIDE); // hide the popup
			}
		}
		if (g_Option_DMS == 0){
			if (wcscmp(className, L"ImmersiveSwitchList") == 0){
				msg->message = WM_NULL;
				g_SwitchList = msg->hwnd;
				ShowWindow(msg->hwnd, SW_HIDE); // hide the popup		
			}
		}

	}

	return CallNextHookEx(hAppManager, code, wParam, lParam);
}

void CloseWinKStart() {
	PostMessage(g_WinKStartManagement, WM_CLOSE, NULL, 0);
}

void ShowWinKStartSettings() {
	PostMessage(g_WinKStartManagement, WM_ACTION_OPENSETTINGSDLG, NULL, 0);
}

void AddContextMenuCmd(HMENU menu, HMENU submenu) {
	bool bRemote = GetSystemMetrics(SM_REMOTESESSION) != 0;
	int iMenuItemCount0 = 0;

	SYSTEM_POWER_CAPABILITIES powerCaps;
	GetPwrCapabilities(&powerCaps);

	if (g_CMO & 128)
		AppendMenuW(menu, MF_STRING, CMD_TASKMANAGER, g_TransactionStrings.GetText(L"Taskmanager"));

	if (g_CMO & 2048)
		AppendMenuW(menu, MF_STRING, CMD_SYSTEMCONTROL, g_TransactionStrings.GetText(L"Systemcontrol"));

	if (g_CMO & 2)
		AppendMenuW(menu, MF_STRING, CMD_EXPLORER, g_TransactionStrings.GetText(L"Windows Explorer"));

	if (g_CMO & 64)
		AppendMenuW(menu, MF_STRING, CMD_RUN, g_TransactionStrings.GetText(L"Run"));

	if (g_CMO & 256)
		AppendMenuW(menu, MF_STRING, CMD_SEARRCH, g_TransactionStrings.GetText(L"Search"));

	iMenuItemCount0 = GetMenuItemCount(menu);
	if (iMenuItemCount0 > 0)
		AppendMenuW(menu, MF_SEPARATOR, 0, 0);

	iMenuItemCount0 = GetMenuItemCount(menu);
	if (g_CMO & 1024)
		AppendMenuW(menu, MF_STRING, CMD_PROGRAMS, g_TransactionStrings.GetText(L"Programs and Features"));

	if (g_CMO & 16384)
		AppendMenuW(menu, MF_STRING, CMD_MOBILITYCENTER, g_TransactionStrings.GetText(L"Mobility center"));

	if (g_CMO & 32768)
		AppendMenuW(menu, MF_STRING, CMD_ENERGYOPTIONS, g_TransactionStrings.GetText(L"Power options"));

	if (g_CMO & 65536)
		AppendMenuW(menu, MF_STRING, CMD_EVENTVIEWER, g_TransactionStrings.GetText(L"Eventviewer"));

	if (g_CMO & 512)
		AppendMenuW(menu, MF_STRING, CMD_SYSTEMPROPERTIES, g_TransactionStrings.GetText(L"System"));

	if (g_CMO & 131072)
		AppendMenuW(menu, MF_STRING, CMD_DEVICEMANAGER, g_TransactionStrings.GetText(L"Device Manager"));

	if (g_CMO & 262144)
		AppendMenuW(menu, MF_STRING, CMD_NETWORKCONNECTIONS, g_TransactionStrings.GetText(L"Network connections"));

	if (g_CMO & 524288)
		AppendMenuW(menu, MF_STRING, CMD_DISKMANAGEMENT, g_TransactionStrings.GetText(L"Diskmanagement"));

	if (g_CMO & 1048576)
		AppendMenuW(menu, MF_STRING, CMD_COMPUTERMANAGEMENT, g_TransactionStrings.GetText(L"Computermanagement"));

	if (GetMenuItemCount(menu) > iMenuItemCount0)
		AppendMenuW(menu, MF_SEPARATOR, 0, 0);
	iMenuItemCount0 = GetMenuItemCount(menu);

	if (g_CMO & 4)
		AppendMenuW(menu, MF_STRING, CMD_COMMANDSHELL, g_TransactionStrings.GetText(L"Commandshell"));

	if (g_CMO & 4096)
		AppendMenuW(menu, MF_STRING, CMD_COMMANDSHELLELEVATED, g_TransactionStrings.GetText(L"Commandshell (Administrator)"));

	if (g_CMO & 8)
		AppendMenuW(menu, MF_STRING, CMD_POWERSHELL, g_TransactionStrings.GetText(L"Powershell"));
	if (g_CMO & 8192)
		AppendMenuW(menu, MF_STRING, CMD_POWERSHELLELEVATED, g_TransactionStrings.GetText(L"Powershell (Administrator)"));

	if (GetMenuItemCount(menu) > iMenuItemCount0)
		AppendMenuW(menu, MF_SEPARATOR, 0, 0);

	if (g_CMO & 16)
		AppendMenuW(menu, MF_STRING, CMD_SETTINGS, g_TransactionStrings.GetText(L"WinKStart Settings"));
	if (g_CMO & 32)
		AppendMenuW(menu, MF_STRING, CMD_EXIT, g_TransactionStrings.GetText(L"WinKStart Exit"));

	if (g_CMO & 2097152)
	{
		//Log off Shutdown Context-Menu-Item is enabled by Settings
		AppendMenuW(menu, MF_SEPARATOR, 0, 0);
		AppendMenuW(menu, MF_POPUP | MF_STRING, (UINT_PTR)submenu, g_TransactionStrings.GetText(L"Log off and Shutdown"));
		//User_Switch Entry
		bool bUserSwitchVisible = true;
		CComPtr<IShellDispatch2> pShellDisp;
		if (SUCCEEDED(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_SERVER, IID_IShellDispatch2, (void**)&pShellDisp)))
		{
			long val;
			if (SUCCEEDED(pShellDisp->IsRestricted(CComBSTR(L"System"), CComBSTR(L"HideFastUserSwitching"), &val)) && val)
				bUserSwitchVisible = false;
		}
		if (bUserSwitchVisible)
			AppendMenuW(submenu, MF_STRING, CMD_SWITCH_USER, g_TransactionStrings.GetText(L"Switch User"));
		//User Log off Entry
		if (g_CLSO & 1) AppendMenuW(submenu, MF_STRING, CMD_LOGOFF, g_TransactionStrings.GetText(L"Log off"));
		//Lock Desktop Entry
		AppendMenuW(submenu, MF_STRING, CMD_LOCK, g_TransactionStrings.GetText(L"Lock"));

		AppendMenuW(submenu, MF_SEPARATOR, 0, 0);
		//Sleep Entry
		if (powerCaps.SystemS1 || powerCaps.SystemS2 || powerCaps.SystemS3)
			AppendMenuW(submenu, MF_STRING, CMD_SLEEP, g_TransactionStrings.GetText(L"Sleep"));
		//Hibernate Entry
		if (powerCaps.HiberFilePresent)
			AppendMenuW(submenu, MF_STRING, CMD_HIBERNATE, g_TransactionStrings.GetText(L"Hibernate"));
		//Restart Entry
		AppendMenuW(submenu, MF_STRING, CMD_RESTART, g_TransactionStrings.GetText(L"Restart"));
		//Show Shutdown Entry
		if (!bRemote && g_CLSO & 2) AppendMenuW(submenu, MF_STRING, CMD_SHUTDOWN, g_TransactionStrings.GetText(L"Shutdown"));
		//Show Disconnect Entry (only if Remote Session)
		if (bRemote && !SHRestricted(REST_NODISCONNECT)) AppendMenuW(submenu, MF_STRING, CMD_DISCONNECT, g_TransactionStrings.GetText(L"Disconnect"));
		//Show Undock Entry (only if Hardware Supports it)
		HW_PROFILE_INFO info;
		GetCurrentHwProfile(&info);
		if (((info.dwDockInfo&(DOCKINFO_DOCKED | DOCKINFO_UNDOCKED)) == DOCKINFO_DOCKED) && g_CLSO & 3)
			AppendMenuW(submenu, MF_STRING, CMD_UNDOCK, g_TransactionStrings.GetText(L"Disconnect"));
	}
}

static void SetShutdownPrivileges(void)
{
	HANDLE hToken;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
	{
		TOKEN_PRIVILEGES tp = { 1 };
		if (LookupPrivilegeValue(NULL, "SeShutdownPrivilege", &tp.Privileges[0].Luid))
			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
		CloseHandle(hToken);
	}
}

static DWORD WINAPI SleepThread(void *param)
{
	SetSuspendState((BOOL)param, FALSE, FALSE);
	return 0;
}

static INT_PTR CALLBACK LogOffDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_INITDIALOG)
	{
		// translate text
		SendDlgItemMessage(hwndDlg, IDC_STATICICON1, STM_SETICON, lParam, 0);
		SetWindowText(hwndDlg, "Log Off Windows");
		SetDlgItemText(hwndDlg, IDC_PROMPT, "Are you sure you want to log off?");
		SetDlgItemText(hwndDlg, IDOK, "&Log Off");
		SetDlgItemText(hwndDlg, IDCANCEL, "&No");
		return TRUE;
	}
	if (uMsg == WM_COMMAND && wParam == IDOK)
	{
		EndDialog(hwndDlg, 1);
		return TRUE;
	}
	if (uMsg == WM_COMMAND && wParam == IDCANCEL)
	{
		EndDialog(hwndDlg, 0);
		return TRUE;
	}
	return FALSE;
}

void ProcessContextMenuCmd(int Command) {
	CComPtr<IShellDispatch2> pShellDisp2;

	if (Command == CMD_EXPLORER){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"; //computer
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_RUN) {
		IShellDispatch* pShellDisp = NULL;

		HRESULT hr = ::CoCreateInstance(CLSID_Shell, NULL,
			CLSCTX_SERVER, IID_IShellDispatch, (LPVOID*)&pShellDisp);

		if (hr == S_OK)
		{
			pShellDisp->FileRun();
			pShellDisp->Release();
			pShellDisp = NULL;
		}
	}
	else if (Command == CMD_COMMANDSHELL) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"cmd.exe";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_COMMANDSHELLELEVATED) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"cmd.exe";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_POWERSHELL) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"powershell";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_POWERSHELLELEVATED){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"powershell";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_SETTINGS){
		ShowWinKStartSettings();
	}
	else if (Command == CMD_EXIT){
		CloseWinKStart();
	}
	else if (Command == CMD_TASKMANAGER) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"taskmgr";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_SEARRCH) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"rundll32.exe";
		shellinfoexec.lpParameters = L" -sta {C90FB8CA-3295-4462-A721-2935E83694BA}";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_SYSTEMCONTROL) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_SYSTEMPROPERTIES) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"-Name Microsoft.System";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else  if (Command == CMD_PROGRAMS) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"-Name Microsoft.ProgramsAndFeatures";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_MOBILITYCENTER) {
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"-Name Microsoft.MobilityCenter";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_ENERGYOPTIONS){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"-Name Microsoft.PowerOptions";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_EVENTVIEWER){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"mmc";
		shellinfoexec.lpParameters = L"eventvwr.msc";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_DEVICEMANAGER){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"-Name Microsoft.DeviceManager";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_NETWORKCONNECTIONS){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"open";
		shellinfoexec.lpFile = L"control";
		shellinfoexec.lpParameters = L"netconnections";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_DISKMANAGEMENT){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"mmc";
		shellinfoexec.lpParameters = L"diskmgmt.msc";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_COMPUTERMANAGEMENT){
		SHELLEXECUTEINFOW shellinfoexec = { sizeof(shellinfoexec) };
		shellinfoexec.lpVerb = L"runas";
		shellinfoexec.lpFile = L"mmc";
		shellinfoexec.lpParameters = L"compmgmt.msc /s";
		shellinfoexec.nShow = SW_SHOWNORMAL;
		ShellExecuteExW(&shellinfoexec);
	}
	else if (Command == CMD_SHUTDOWN)
	{
		SetShutdownPrivileges();
		if (IsWindows8OrGreater())
			ExitWindowsEx(EWX_SHUTDOWN | EWX_HYBRID_SHUTDOWN, 0);
		else
			ExitWindowsEx(EWX_SHUTDOWN, 0);
	}
	else if (Command == CMD_RESTART)
	{
		SetShutdownPrivileges();
		ExitWindowsEx(EWX_REBOOT, 0);
	}
	else if (Command == CMD_SLEEP)
	{
		CreateThread(NULL, 0, SleepThread, (void*)FALSE, 0, NULL);
	}
	else if (Command == CMD_HIBERNATE)
	{
		CreateThread(NULL, 0, SleepThread, (void*)TRUE, 0, NULL);
	}
	else if (Command == CMD_LOCK)
	{
		LockWorkStation();
	}
	else if (Command == CMD_LOGOFF)
	{
		HMODULE hShell32 = GetModuleHandle("Shell32.dll");
		HICON icon = LoadIcon(hShell32, MAKEINTRESOURCE(45));
		INT_PTR res = DialogBoxParam(g_Instance, MAKEINTRESOURCE(IDD_LOGOFF), NULL, LogOffDlgProc, (LPARAM)icon);
		DestroyIcon(icon);
		if (res)
			ExitWindowsEx(EWX_LOGOFF, 0);
	}
	else if (Command == CMD_SWITCH_USER)
	{
		WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, FALSE);
	}
	else if (Command == CMD_WINDOWS_HELP)
	{
		if (SUCCEEDED(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_SERVER, IID_IShellDispatch2, (void**)&pShellDisp2)))
			pShellDisp2->Help();
	}
	else if (Command == CMD_DISCONNECT)
	{
		WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, FALSE);
	}
	else if (Command == CMD_UNDOCK)
	{
		if (SUCCEEDED(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_SERVER, IID_IShellDispatch2, (void**)&pShellDisp2)))
			pShellDisp2->EjectPC();
	}
}

static LRESULT CALLBACK MouseHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
	MSG *msg;
	msg = (MSG *)lparam;

	if (wparam == WM_LBUTTONDOWN) {
		POINT ptCurrentCursorPos;
		GetCursorPos(&ptCurrentCursorPos);

		HWND MousePosHandle = WindowFromPoint(ptCurrentCursorPos);
		if (g_bReplaceButton){
			HWND hStartButton = GetTaskbarStartButtonFromHandle(MousePosHandle);

			if (hStartButton != NULL){//MousePosHandle == g_TaskBar) {
				//RECT rcTaskbar = GetStartButtonStartPosition(hStartButton);
				RECT rcTaskbar;// = GetTaskbarStartButtonRect(g_TaskBar);

				GetWindowRect(MousePosHandle, &rcTaskbar);

				POINT pStartPos;
				UINT uiPosition = GetStartButtonPosition(hStartButton);

				if (uiPosition == ABE_LEFT) {
					pStartPos.x = rcTaskbar.right;
					pStartPos.y = rcTaskbar.top;
				}
				else if (uiPosition == ABE_TOP) {
					pStartPos.x = rcTaskbar.left;
					pStartPos.y = rcTaskbar.bottom;
				}
				else {
					pStartPos.x = rcTaskbar.left;
					pStartPos.y = rcTaskbar.top;
				}

				if (PtInRect(&GetTaskbarStartButtonRect(MousePosHandle), ptCurrentCursorPos) == TRUE){
					PostMessage(hStartButton, WM_MOUSEACTIVATE, NULL, 'CLSM');
					//Running Command
					bool bShiftPressed = (GetAsyncKeyState(VK_SHIFT) < 0);
					g_bNotReplacedSecondStartButtonPressed = false;
					if (bShiftPressed) {
						if (g_SBMO == 1) {
							//Opens WinKStart - Startmenu
							PostMessage(g_WinKStartManagement, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));
						}
						else if (g_SBMO == 2) {
							//Opens Metro StartScreen
							PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');
						}
					}
					else {
						if (g_BMO == 1) {
							//Opens WinKStart - Startmenu
							PostMessage(g_WinKStartManagement, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));
						}
						else if (g_BMO == 2) {
							//Opens Metro StartScreen
							PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');
						}
					}
				}
			}
			else {
				//LogMessage("WM_LBUTTONDOWN StartButton is NULL", LOG_ACTIONS);
				if (IsTaskbarStartButton(MousePosHandle)){
					g_bNotReplacedSecondStartButtonPressed = true;
					PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');
				}
			}
		}
		else {
			//LogMessage("WM_LBUTTONDOWN StartButton Handle: ", MousePosHandle, LOG_ACTIONS);
			if (IsTaskbarStartButton(MousePosHandle)){
				HWND tmpTaskBarHandle = GetTaskbarHandleFromButton(MousePosHandle);
				RECT rcTaskbar;

				GetWindowRect(MousePosHandle, &rcTaskbar);

				POINT pStartPos;
				UINT uiPosition = GetStartButtonTPosition(tmpTaskBarHandle);

				if (uiPosition == ABE_LEFT) {
					pStartPos.x = rcTaskbar.right;
					pStartPos.y = rcTaskbar.top;
				}
				else if (uiPosition == ABE_TOP) {
					pStartPos.x = rcTaskbar.left;
					pStartPos.y = rcTaskbar.bottom;
				}
				else {
					pStartPos.x = rcTaskbar.left;
					pStartPos.y = rcTaskbar.top;
				}

				bool bShiftPressed = (GetAsyncKeyState(VK_SHIFT) < 0);
				if (bShiftPressed) {
					if (g_SBMO == 1) {
						//Opens WinKStart - Startmenu
						PostMessage(g_WinKStartManagement, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));
					}
					else if (g_SBMO == 2) {
						//Opens Metro StartScreen
						PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');
					}
				}
				else {
					if (g_BMO == 1) {
						//Opens WinKStart - Startmenu
						PostMessage(g_WinKStartManagement, WM_ACTION_STARTMENU, uiPosition, MAKELPARAM(pStartPos.x, pStartPos.y));
					}
					else if (g_BMO == 2) {
						//Opens Metro StartScreen
						PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');
					}
				}
			}
		}
	}
	else if (wparam == WM_LBUTTONUP) {
		g_bNotReplacedSecondStartButtonPressed = false;
		POINT ptCurrentCursorPos;
		GetCursorPos(&ptCurrentCursorPos);

		HWND MousePosHandle = WindowFromPoint(ptCurrentCursorPos);
		if (g_bReplaceButton){
			HWND hStartButton = GetTaskbarStartButtonFromHandle(MousePosHandle);
			if (hStartButton != NULL){ // MousePosHandle == g_TaskBar) {

				if (PtInRect(&GetTaskbarStartButtonRect(MousePosHandle), ptCurrentCursorPos) == TRUE){
					PostMessage(hStartButton, WM_LBUTTONUP, NULL, 'CLSM');

				}
			}
		}
	}
	else if (wparam == WM_RBUTTONUP) {

		if (g_CMO & 1){
			

			POINT ptCurrentCursorPos;
			GetCursorPos(&ptCurrentCursorPos);
			HWND MousePosHandle = WindowFromPoint(ptCurrentCursorPos);
			HWND hStartButton = GetTaskbarStartButtonFromHandle(MousePosHandle);
			
			if (hStartButton != NULL){

				HMENU menu = CreatePopupMenu();
				HMENU submenu = CreatePopupMenu();

				AddContextMenuCmd(menu, submenu);

				int iCmd = TrackPopupMenu(menu, TPM_LEFTBUTTON | TPM_RETURNCMD, ptCurrentCursorPos.x, ptCurrentCursorPos.y, 0, hStartButton, NULL);
				
				ProcessContextMenuCmd(iCmd);

				DestroyMenu(submenu);
				DestroyMenu(menu);
			}
		}
	}
	else if (wparam == WM_MOUSEFIRST || wparam == WM_MOUSEMOVE){  //the Message WM_MOUSEFIRST is the same Message value how WM_MOUSEMOVE
		g_bNotReplacedSecondStartButtonPressed = false;
		POINT ptCurrentCursorPos;
		GetCursorPos(&ptCurrentCursorPos);

		HWND MousePosHandle = WindowFromPoint(ptCurrentCursorPos);
		if (g_bReplaceButton){
			HWND hStartButton = GetTaskbarStartButtonFromHandle(MousePosHandle);
			if (hStartButton != NULL){ //MousePosHandle == g_TaskBar) {

				if (PtInRect(&GetTaskbarStartButtonRect(MousePosHandle), ptCurrentCursorPos) == TRUE){
					if (g_bLastStateMouse != WM_MOUSEFIRST){
						g_bLastStateMouse = WM_MOUSEFIRST;
						//send a WM_MOUSEENTER to the startbutton to know mouse is in
						PostMessage(hStartButton, WM_MOUSEMOVE, NULL, 'CLSM');
					}
				}
			}
			else {
				if (g_bLastStateMouse != -1){
					SetDefaultButtonState();
					//PostMessage(g_WinStartButton, WM_LBUTTONUP, NULL, 'CLSM');
					//send a WM_MOUSELEAVE to the startbutton to know mouse is out
					g_bLastStateMouse = -1;
				}
			}
		}
	}


	return CallNextHookEx(hMouse, code, wparam, lparam);
}

static LRESULT CALLBACK KeyboardHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
	static bool s_bLWinPressed, s_bRWinPressed, s_bShiftPressed, s_bF4Pressed, s_bCanWinKeyProcess;
	KBDLLHOOKSTRUCT *pKbd = (KBDLLHOOKSTRUCT*)lparam;
	//get true if the user has the left win key button pressed
	s_bLWinPressed = (pKbd->vkCode == VK_LWIN);
	//get true if the user has the right win key button pressed
	s_bRWinPressed = (pKbd->vkCode == VK_RWIN);
	s_bShiftPressed = (GetAsyncKeyState(VK_SHIFT) < 0); //ask settings if this option is active	
	s_bF4Pressed = (pKbd->vkCode == VK_ESCAPE);
	////LogMessage("Shift pressed", s_bShiftPressed, LOG_DEBUG);

	//s_bF4Pressed = (pKbd->vkCode == VK_ESCAPE);

	if (wparam == WM_KEYUP)
	{
		if ((s_bLWinPressed || s_bRWinPressed) && s_bShiftPressed)
		{
			//toogleStartMenu(WM_KEYUP, true);
			PostMessage(g_ProgWin, WM_SYSCOMMAND, SC_TASKLIST, 'CLSM');		
		}
		if (s_bF4Pressed)
			PostMessage(g_WinKStartManagement, WM_ACTION_WINKSTART_HIDE, 0, 0);
	}	
	return CallNextHookEx(hKeyboard, code, wparam, lparam);
}

LRESULT CALLBACK HookStartButton(int code, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	msg = (MSG *)lParam;
	LogMessage(*msg, "HookStartButton", LOG_MESSAGES);
	if (wParam == WM_LBUTTONDOWN)
		LogMessage("WM_LBUTTONDOWN", LOG_MESSAGES);

	return CallNextHookEx(hTaskBarHook, code, wParam, lParam);
}

static BOOL CALLBACK FindStartButtonEnum(HWND hwnd, LPARAM lParam)
{
	// look for top-level window in the current thread with class "button"
	wchar_t name[256];
	GetClassNameW(hwnd, name, _countof(name));	
	if (_wcsicmp(name, L"button") != 0)
		return TRUE;
	g_WinStartButton = hwnd;
	return FALSE;
}

static BOOL CALLBACK FindTaskBarEnum(HWND hwnd, LPARAM lParam)
{
	// look for top-level window with class "Shell_TrayWnd" and process ID=lParam
	DWORD process;
	GetWindowThreadProcessId(hwnd, &process);
	if (process != lParam) return TRUE;
	wchar_t name[256];
	GetClassNameW(hwnd, name, _countof(name));
	if (_wcsicmp(name, L"Shell_TrayWnd") != 0) return TRUE;
	g_TaskBar = hwnd;
	return FALSE;
}

void ResetHotCorners(void)
{
	for (std::set<HWND>::const_iterator it = g_EdgeWindows.begin(); it != g_EdgeWindows.end(); ++it)
		ShowWindow(*it, SW_SHOW);
	g_EdgeWindows.clear();
}

void RestoreStartButton(void) {

	CloseStartMenu();

	LogMessage("Restore Hot Corners", LOG_ACTIONS);
	//Restore Hot Corners
	ResetHotCorners();

	LogMessage("Restore SwitchList", LOG_ACTIONS);
	//Restore Switch List
	if (g_SwitchList) SendMessage(g_SwitchList, SW_SHOW, 0, 0);
}

void HasMovedTaskbar() {
	CheckTaskbarMoved();
}

void HasInstalledNewScreen() {

}

void SetOptions(int BMO, int BKO, int SBMO, int SBKO, int MBMO, 
				int TMBMO, LPWSTR *SBS, int DMS, int DHE, int RAFG, 
				int CMO, bool ReplaceButton, bool ReplaceAllTaskbars,
				LPWSTR *TranslatinFile, LPWSTR *LoggingPathFile, int CLSO){
	//BMO - Button Mouse Open (0 - Nothing, 1 - WinKStart, 2 - Metro)
	//BKO - Button Key Open (0 - Nothing, 1 - WinKStart, 2 - Metro)
	//SBMO - Shift Button Mouse Open (0 - Nothing, 1 - WinKStart, 2 - Metro)
	//SBKO - Shift Button Key Open (0 - Nothing, 1 - WinKStart, 2 - Metro)
	//MBMO - Move Button Mouse Open (0 - Nothing, 1 - WinKStart, 2 - Metro)
	//TMBMO - Delay-time MBMO Example 100 
	//SBS - Start Button Symbol (Path for Windows Bitmap Image)
	//DMS - Disable Metro Screen (0 - Disable, 1 - Enable)
	//DHE - Disable Hot Edges (0 - Disable, 1 - Enable)
	//RAFG - Restore After Failed GUI in Seconds (Example 30) 
	//CMO - Context Menu Options (67 for Example)
	g_BMO = BMO;
	g_Option_BKO = BKO;
	g_SBMO = SBMO;
	g_Option_SBKO = SBKO;
	g_MBMO = MBMO;
	g_TMBMO = TMBMO;
	g_Option_DMS = DMS;
	g_Option_DHE = DHE;
	g_RAFG = RAFG;
	g_CMO = CMO;
	g_SBS = SBS;
	g_CLSO = CLSO;

	g_bReplaceAllTasksbars = ReplaceAllTaskbars;
	g_bReplaceButton = ReplaceButton;
	g_OptionTranslationsPath = TranslatinFile;
	g_OptionLoggingPath = LoggingPathFile;

	SetLogPath(g_OptionLoggingPath[0]);
	SetLogFileName(L"testlogging.xml");
}

void InitButton(void) {

	g_TestValue = 5;

	SetLogPath(g_OptionLoggingPath[0]);
	SetLogFileName(L"testlogging.xml");
	SetLoggingLevel(LOG_ACTIONS | LOG_HINT | LOG_ERROR); //LOG_DEBUG |          | LOG_MESSAGES

	LogMessage("Initialize StartMenu.", LOG_ACTIONS);
	
	if (!g_bReplaceButton)
		g_bReplaceButton = IsWindows8OrGreater() && !IsWindows8Point1OrGreater();

	if (g_bReplaceButton)
		LogMessage("Button - Mode: replace existing Start Button or create new (if OS is Windows 8). ", LOG_ACTIONS);
	else
		LogMessage("Button - Mode: use existing Start Button.. ", LOG_ACTIONS);

	wchar_t *sFolderPath = NULL;
	SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &sFolderPath);

	DWORD process;

	g_WinKStartManagement = FindWindowExW(NULL, NULL, L"WinKStart.CWinKStartManagement", NULL);	

	//Find Progman
	g_ProgWin = FindWindowExW(NULL, NULL, L"Progman", NULL);
	//only run code if Progman was founded, 
	//if not explorer is current restarting or not running
	//and we must look any time if explorer is loading
	if (g_ProgWin) {
		DWORD threadProgman = GetWindowThreadProcessId(g_ProgWin, &process);
		LogMessage("Progman Handle: ", g_ProgWin, LOG_DEBUG);
		//Find Taskbar
		LogMessage("Find Taskbar ", LOG_DEBUG);
		EnumWindows(FindTaskBarEnum, process);

		LogMessage("Taskbar Handle: ", g_TaskBar, LOG_DEBUG);
		if (g_TaskBar){
			g_MainTaskBar = g_TaskBar;
			DWORD threadTaskBar = GetWindowThreadProcessId(g_TaskBar, NULL);
			//Find ApplicationManager
			HWND AppManager = FindWindow("ApplicationManager_DesktopShellWindow", NULL);
			DWORD threadApplicationManager = GetWindowThreadProcessId(AppManager, NULL);
			LogMessage("ApplicationManager Handle: ", g_ProgWin, LOG_DEBUG);
			g_TransactionStrings.LoadStrings(g_OptionTranslationsPath[0]);

			//InitStartButton
			InitStartButton();

			//Install TaskBar Hook
			//if (!hTaskBarHook)
			//	hTaskBarHook = SetWindowsHookEx(WH_GETMESSAGE, HookTaskBar, g_Instance, threadTaskBar);
			LogMessage("Install Taskbar Hook: ", (bool)hTaskBarHook != 0, LOG_ACTIONS);

			//Install Progman Hook
			if (!hProgmanHook)
				hProgmanHook = SetWindowsHookEx(WH_GETMESSAGE, HookProgMan, g_Instance, threadProgman);
			LogMessage("Install Progman Hook: ", (bool)hProgmanHook != 0, LOG_ACTIONS);

			//Install ApplicationManager Hook
			if (!hAppManager)
				hAppManager = SetWindowsHookEx(WH_GETMESSAGE, HookAppManager, g_Instance, threadApplicationManager);
			LogMessage("Install ApplicationManager Hook: ", (bool)hAppManager != 0, LOG_ACTIONS);

			//Install Mouse Hook
			if (!hMouse)
				hMouse = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)MouseHookCallback, g_Instance, 0);
			LogMessage("Install Mouse Hook: ", (bool)hMouse != 0, LOG_ACTIONS);

			//Install Keyboard Hook
			if (!hKeyboard)
				hKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardHookCallback, g_Instance, 0);
			LogMessage("Install Keyboard Hook: ", (bool)hKeyboard != 0, LOG_ACTIONS);


			if (!hNewTaskbar)
				hNewTaskbar = SetWindowsHookEx(WH_CBT, HookNewTaskbar, g_Instance, 0);
			//if (!hSMTaskBarHook)
			//	hSMTaskBarHook = SetWindowsHookEx(WH_CALLWNDPROC, SMHookTaskBar, g_Instance, 0); //WH_CALLWNDPROC  WH_CBT
			//LogMessage("Install SMTaskbar Hook: ", (bool)hSMTaskBarHook != 0, LOG_ACTIONS);

			//LogMessage("NewStartButton Handle: ", g_WinStartButton, LOG_DEBUG);
			//if (g_bReplaceButton) {
			//	//if we create our own startbutton, install a hook for this
			//	DWORD StartButtonThread = GetWindowThreadProcessId(g_WinStartButton, NULL);
				//if (!hStartButton)
				//	hStartButton = SetWindowsHookEx(WH_GETMESSAGE, HookStartButton, NULL, GetCurrentThreadId());

			//	LogMessage("Install StartButton Hook: ", (bool)hStartButton != 0, LOG_ACTIONS);
			//}
		}
	}
}

void CloseButton(void)
{


	if (hNewTaskbar != NULL)
		UnhookWindowsHookEx(hNewTaskbar);

	if(hkKey !=NULL)
		UnhookWindowsHookEx(hkKey);

	LogMessage("Remove Keyboard Hook ", LOG_ACTIONS);
	if (hKeyboard)
		UnhookWindowsHookEx(hKeyboard);

	LogMessage("Remove Mouse Hook ", LOG_ACTIONS);
	if (hMouse)
		UnhookWindowsHookEx(hMouse);

	LogMessage("Remove ApplicationManager Hook ", LOG_ACTIONS);
	if (hAppManager)
		UnhookWindowsHookEx(hAppManager);

	LogMessage("Remove Progman Hook ", LOG_ACTIONS);
	if (hProgmanHook)
		UnhookWindowsHookEx(hProgmanHook);

	LogMessage("Remove Taskbar Hook ", LOG_ACTIONS);
	if (hTaskBarHook)
		UnhookWindowsHookEx(hTaskBarHook);

	//LogMessage("Remove SMTaskbar Hook ", LOG_ACTIONS);
	//if (hSMTaskBarHook)
	//	UnhookWindowsHookEx(hSMTaskBarHook);

	//if (hStartButton)
	//	UnhookWindowsHookEx(hStartButton);

	//Close Start Button
	RestoreStartButton();

	hkKey = NULL;
	hKeyboard = NULL;
	hMouse = NULL;
	hAppManager = NULL;
	hProgmanHook = NULL;
	hTaskBarHook = NULL;
	hSMTaskBarHook = NULL;
	hStartButton = NULL;
}

